﻿namespace Whut.ObjectSharePointMapper.Internals
{
    using System;
    using System.Collections.Generic;
    using Microsoft.SharePoint;

    public class SessionLevelCache
    {
        private Dictionary<Type, Dictionary<int, object>> entityCache = new Dictionary<Type, Dictionary<int, object>>();

        private Dictionary<Type, Dictionary<int, SPListItem>> listItemCache = new Dictionary<Type, Dictionary<int, SPListItem>>();

        public TEntity TryFindEntity<TEntity>(int id)
        {
            return (TEntity)this.TryFindEntity(typeof(TEntity), id);
        }

        public object TryFindEntity(Type entityType, int id)
        {
            if (!this.entityCache.ContainsKey(entityType))
            {
                return null;
            }

            var entities = this.entityCache[entityType];
            if (!entities.ContainsKey(id))
            {
                return null;
            }

            return entities[id];
        }

        public SPListItem TryFindSPListItem<TEntity>(int id)
        {
            Type entityType = typeof(TEntity);
            if (!this.listItemCache.ContainsKey(entityType))
            {
                return null;
            }

            var listItems = this.listItemCache[entityType];
            if (!listItems.ContainsKey(id))
            {
                return null;
            }

            return listItems[id];
        }

        public void Store<TEntity>(SPListItem item, TEntity entity)
        {
            Type entityType = typeof(TEntity);
            if (!this.entityCache.ContainsKey(entityType))
            {
                this.entityCache[entityType] = new Dictionary<int, object>();
                this.listItemCache[entityType] = new Dictionary<int, SPListItem>();
            }

            this.entityCache[entityType][item.ID] = entity;
            this.listItemCache[entityType][item.ID] = item;
        }

        public void Remove<TEntity>(int id)
        {
            Type entityType = typeof(TEntity);
            if (!this.entityCache.ContainsKey(entityType))
            {
                return;
            }

            var entities = this.entityCache[entityType];
            var listItems = this.listItemCache[entityType];
            if (!entities.ContainsKey(id))
            {
                return;
            }

            entities.Remove(id);
            listItems.Remove(id);
        }
    }
}
